<?php
require_once("EmbraceTable.php");
require_once("EmbraceField.php");
require_once("EmbraceMethod.php");
require_once("ITransformer.php");
require_once("InterfaceTransformer.php");
require_once("AbstractTransformer.php");
require_once("BasicTransformer.php");

/**
 * represents the complete structutr of the model.
 * 
 * @author s.marletta
 * @version $Id: EmbraceModel.php 6 2009-04-28 20:11:07Z embrace.toolkit $
 */
class EmbraceModel implements ITransformer {
	/**
	 * name of the model.
	 * @var String
	 */
	private $modelName;
	
	/**
	 * version of embrace.
	 * @var String
	 */
	private $embraceVersion;
	
	/**
	 * settings object.
	 * @var EmbraceSettings
	 */
	private $settings;
	
	/**
	 * parameters object.
	 * @var EmbraceParameters
	 */
	private $parameters;
	
	/**
	 * Containing all tables as EmbraceTable
	 * @var Array
	 */
	private $arrTables;
	
	/**
	 * Containing all fields as EmbraceField
	 * @var Array
	 */
	private $arrFields;
	
	/**
	 * Containing all methods as EmbraceMethod
	 * @var Array
	 */
	private $arrMethods;
	
	/**
	 * creates Embrace model
	 * @param $modelName name of the Model
	 * @param $embraceVersion version of the embrace engine.
	 */
	public function EmbraceModel($modelName, $embraceVersion) {
		$this->modelName = $modelName;
		$this->embraceVersion = $embraceVersion;

		if($this->embraceVersion != "1.0")
			throw new Exception("Illegal Embrace version defined.");
			
		$this->arrTables = Array();
		$this->arrFields = Array();
		$this->arrMethods = Array();
	}
	
	/**
	 * Sets the settings object
	 * @param $settings the enw settings
	 */
	public function setSettings(EmbraceSettings $settings) {
		$this->settings = $settings;	
	}

	/**
	 * Sets the parameter object.
	 * @param $params the new parameters.
	 */
	public function setParameters(EmbraceParameters $params) {
		$this->parameters = $params;
	}
	
	/**
	 * Returns the parameter object.
	 * @return EmbraceParameters
	 */
	public function getParameters() {
		return $this->parameters;
	}
	
	/**
	 * Starts the transformation process.
	 * 
	 * @param $data the data to be transformed. 
	 */
	public function transform($data) {
		$this->parseTables($data);	
		$this->parseFields($data);
		$this->parseMethods($data);
		
		$serviceDir = mkdirRecursive(
			"output" . $this->settings->getSetting("service_path"),
			0777
		);
		
		if(!$serviceDir)
			throw new Exception("Unable to create service path.");
		
		$interfaceTransformer = new InterfaceTransformer();
		$interfaceTransformer->transform($this);
		
		$abstractTransformer = new AbstractTransformer();
		$abstractTransformer->transform($this);
		
		$basicTransformer = new BasicTransformer();
		$basicTransformer->transform($this);
	}
	
	/**
	 * genereates direct output of model information.
	 */
	public function createReport() {
		?>
		<div style="line-height: 30px;">
			Model Information
		</div>
		<div style="border: 1px solid #CCCCCC; padding: 6px;">
		<table cellspacing="0" cellpadding="0" style="width: 100%;">
		  	<tr>
		    	<th style="text-align: left; width: 175px;">description</th>
		    	<th style="text-align: left; width: 175px;">value</th>
		  	</tr>
			<tr>
				<td style="text-align: left; width: 175px;">tables: </td>
				<td style="text-align: left; width: 175px;"><?php echo count($this->arrTables); ?></td>
			</tr>
			<tr>
				<td style="text-align: left; width: 175px;">fields: </td>
				<td style="text-align: left; width: 175px;"><?php echo count($this->arrFields); ?></td>
			</tr>
			<tr>
				<td style="text-align: left; width: 175px;">methods: </td>
				<td style="text-align: left; width: 175px;"><?php echo count($this->arrMethods); ?></td>
			</tr>
		</table>
		</div>
		<?php		
	}
	
	/**
	 * Parse alle tables of the model.
	 * @param $xml the xml object
	 */
	protected function parseTables($xml) {
		$arrTablesFromXml = $xml->xpath("/embrace_model/tables/embrace_table");
		
		foreach($arrTablesFromXml as $xmlTable) {
			$empTable = new EmbraceTable(
				"".$xmlTable->name, 
				"".$xmlTable->primary_key
			);	

			$this->arrTables[] = $empTable;
		}
		
		if(count($this->arrTables) <= 0)
			throw new Exception("No Tables found.");
	}
	
	/**
	 * Parse all fields of the modell
	 * @param $xml the xml object
	 */
	protected function parseFields($xml) {
		$arrFieldsFromXml = $xml->xpath("/embrace_model/fields/embrace_field");
		
		foreach($arrFieldsFromXml as $xmlField) {
			$empField = new EmbraceField(
				"".$xmlField->name,
				"".$xmlField->access,
				"".$xmlField->table
			);

			$this->arrFields[] = $empField;
		}
		
		if(count($this->arrFields) <= 0)
			throw new Exception("No fields found.");
	}

	/**
	 * Parse all methods of the model.
	 * @param $xml the xml object
	 */
	protected function parseMethods($xml) {
		$arrMethodsFromXml = $xml->xpath(
			"/embrace_model/methods/embrace_method"
		);
		
		foreach($arrMethodsFromXml as $xmlMethod) {
			$empMethod = new EmbraceMethod(
				"".$xmlMethod->name,
				"".$xmlMethod->type
			);
			
			$this->arrMethods[] = $empMethod;
		}

		if(count($this->arrMethods) <= 0)
			throw new Exception("No methods found.");
	}
	
	/**
	 * returns the EmbraceSettings object.
	 * @return EmbraceSettings
	 */
	public function getSettings() {
		return $this->settings;
	}
	
	/**
	 * Returns the name of the model.
	 * @return String
	 */
	public function getName() {
		return $this->modelName;
	}
	
	/**
	 * returns the fields array to the transformers.
	 * @return Array|Boolean false if not array.
	 */
	public function getFields() {
		return is_array($this->arrFields) ? $this->arrFields : false;
	}
	
	/**
	 * returns the methods array to the transformers.
	 * @return Array|Boolean fals if not array.
	 */
	public function getMethods() {
		return is_array($this->arrMethods) ? $this->arrMethods : false;
	}
	
	/**
	 * returns the array of tables
	 * @return Array|Boolean false if not array.
	 */
	public function getTables() {
		return is_array($this->arrTables) ? $this->arrTables : false;
	}
}
?>